import * as cc from "cc";

const { ccclass, menu, property } = cc._decorator;

export interface ButtonLongPressParams{
    /**连续回调 once为true,只触发一次,并且endClickListener 不再回调 */
    callBack: (event: cc.EventTouch) => void, 
    /**结束回调 没触发连续回调时,松开按钮回调一次 */
    endCallback: (event: cc.EventTouch) => void, 
    /**是否播放点击动画,默认不播放 */
    anim: boolean, 
    /**回调绑定目标对象 */
    target?: any, 
    /**触发长按间隔 */
    interval?: number, 
    /**是否一次性回调,true */
    once?: boolean
}

@ccclass
@menu("扩展组件/BtnLongPress")
export class ButtonLongPress extends cc.Component {
    private data: ButtonLongPressParams = null;
    
    private isCanCallBack: boolean = false
    private time: number = 0;
    private speed: number = 1;
    private startEventTouch: cc.EventTouch = null;

    onLoad() {
        this.node.on(cc.Node.EventType.TOUCH_START, this.onClickStart, this);
        this.node.on(cc.Node.EventType.TOUCH_MOVE, this.onClickMove, this);
        this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.onClickEnd, this);
        this.node.on(cc.Node.EventType.TOUCH_END, this.onClickEnd, this);
    }

    onDestroy() {
        this.node.off(cc.Node.EventType.TOUCH_START, this.onClickStart, this);
        this.node.off(cc.Node.EventType.TOUCH_MOVE, this.onClickMove, this);
        this.node.off(cc.Node.EventType.TOUCH_CANCEL, this.onClickEnd, this);
        this.node.off(cc.Node.EventType.TOUCH_END, this.onClickEnd, this);
    }

    public init(params:ButtonLongPressParams) {
        this.data = params;
        this.data.interval = params.interval ? params.interval : 0.5;
        this.data.target = params.target ? params.target : this;
        this.data.anim = params.anim ? params.anim : false;
        this.data.once = params.once ? params.once : false;
        this.data.anim && this.addButtonComponent();
    }

    onClickStart(event: cc.EventTouch) {
        if (!this.data) {
            return;
        }
        this.startEventTouch = event;
        if (this.data.once) {
            this.data.callBack && this.data.callBack.bind(this.data.target)(this.startEventTouch);
            this.isCanCallBack = false;
        } else {
            this.speed = 1;
            this.time = 0;
            this.isCanCallBack = true;
        }
    }
    onClickMove() { }
    onClickEnd(event: cc.EventTouch) {
        if (!this.data) {
            return;
        }
        this.data.endCallback && this.data.endCallback.bind(this.data.target)(event);
        this.isCanCallBack = false;
    }
    
    update(dt) {
        if (!this.isCanCallBack) {
            return;
        }
        if (this.data.callBack == null) {
            return;
        }
        if (this.data.once) {
            this.time += dt;
        } else {
            this.time += dt * this.speed;
            this.speed += dt * 5;
        }
        if (this.time >= this.data.interval) {
            this.time = 0;
            this.data.callBack && this.data.callBack.bind(this.data.target)(this.startEventTouch);
        }
    }
    
    addButtonComponent(){
        let button = this.node.getComponent<cc.Button>(cc.Button);
        if (!button) {
            button = this.node.addComponent<cc.Button>(cc.Button);
            button.transition = cc.Button.Transition.SCALE;
            button.zoomScale = 0.9;
            button.duration = 0.1;
            button.interactable = true;
        }
    }
    
}
